package com.yhxd.modular.reference.controller;

import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.yhxd.modular.reference.entity.Directory;
import com.yhxd.modular.reference.entity.PublicFile;
import com.yhxd.modular.reference.entity.QPublicFile;
import com.yhxd.modular.reference.service.DirectoryService;
import com.yhxd.modular.reference.service.PublicFileService;
import com.yhxd.modular.system.entity.Config;
import com.yhxd.modular.system.vo.ResultVo;
import com.yhxd.utils.RedissonUtils;
import io.swagger.annotations.Api;
import org.apache.commons.io.IOUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/ref/pub")
@Api
public class PublicController {

    @Autowired
    private DirectoryService directoryService;

    @Autowired
    private PublicFileService publicFileService;

    /**
     * 跳转到列表页
     *
     * @return
     */
    @GetMapping(value = "/list")
    @RequiresPermissions("pub_list")
    public String list(Model model) {
        Map<String, Config> configMap = (Map<String, Config>) RedissonUtils.getObject("config");
        String fileExts = configMap.get("file_format").getConfValue().replaceAll(",", "|");
        Long fileSize = Long.parseLong(configMap.get("attachment_key").getConfValue()) * 1024;
        model.addAttribute("fileExts", fileExts);
        model.addAttribute("fileSize", fileSize);
        return "mng/reference/pub_list";
    }

    @GetMapping(value = "/findAll")
    @RequiresPermissions("pub_list")
    @ResponseBody
    public ResultVo findAll() {
        try {
            List<Directory> directoryList = this.directoryService.findAll();
            Directory rootDirectory = new Directory();
            rootDirectory.setId(0L);
            rootDirectory.setDirName("全部");
            directoryList.add(rootDirectory);

            return ResultVo.success(directoryList);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error(e.getMessage());
        }
    }

    @PostMapping(value = "/upload")
    @ResponseBody
    public ResultVo upload(HttpServletRequest request) {
        try {
            String url = this.publicFileService.upload(request);
            return ResultVo.success(url);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error(e.getMessage());
        }
    }

    /**
     * 删除目录
     *
     * @param ids
     * @return
     */
    @PostMapping(value = "/delDir")
    @ResponseBody
    public ResultVo delDir(String ids) {
        try {
            this.directoryService.delDir(ids);
            return ResultVo.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error(e.getMessage());
        }
    }

    /**
     * 编辑目录
     *
     * @param id
     * @param newName
     * @return
     */
    @PostMapping(value = "/editDir")
    @ResponseBody
    public ResultVo editDir(Long id, String newName) {
        try {
            this.directoryService.editDir(id, newName);
            return ResultVo.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error(e.getMessage());
        }
    }

    /**
     * 新增目录
     *
     * @param id
     * @param childName
     * @return
     */
    @PostMapping(value = "/addDir")
    @ResponseBody
    public ResultVo addDir(Long id, String childName) {
        try {
            Directory directory = this.directoryService.addDir(id, childName);
            return ResultVo.success(directory);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error(e.getMessage());
        }
    }

    /**
     * 多条件分页查询
     *
     * @param page
     * @param limit
     * @param dirId
     * @param fileName
     * @param createName
     * @param createTime
     * @return
     */
    @PostMapping(value = "/findList")
    @ResponseBody
    public ResultVo findList(Integer page, Integer limit, Long dirId, String fileName, String createName, String createTime) {
        try {
            QPageRequest pageRequest = QPageRequest.of(page - 1, limit, new OrderSpecifier(Order.DESC, QPublicFile.publicFile.id));
            Page<PublicFile> filePage = this.publicFileService.findAll(pageRequest, dirId, fileName, createName, createTime);
            return ResultVo.success(filePage);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error(e.getMessage());
        }
    }

    /**
     * 修改备注
     *
     * @return
     */
    @PostMapping(value = "/editNote")
    @ResponseBody
    public ResultVo editNote(Long id, String note) {
        try {
            this.publicFileService.editNote(id, note);
            return ResultVo.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error(e.getMessage());
        }
    }

    /**
     * 删除
     *
     * @return
     */
    @GetMapping(value = "/delFile/{id}")
    @ResponseBody
    public ResultVo delFile(@PathVariable("id") Long id) {
        try {
            this.publicFileService.deleteById(id);
            return ResultVo.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error(e.getMessage());
        }
    }

    /**
     * 下载
     *
     * @return
     */
    @GetMapping(value = "/downFile/{id}")
    @ResponseBody
    public void downFile(HttpServletResponse response, @PathVariable("id") Long id) {
        try {
            PublicFile publicFile = this.publicFileService.findById(id);
            FileInputStream fis = new FileInputStream(publicFile.getLocalpath());
            ServletOutputStream out = response.getOutputStream();

            response.setContentType("application/octet-stream");
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(publicFile.getFileName() + "." + publicFile.getSuffix(), "UTF-8"));
            response.setHeader("Content-Length", String.valueOf(fis.available()));

            IOUtils.copy(fis, out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
